package com.sm.scorpio.ui.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.StateSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.view.SupportMenuInflater;
import androidx.appcompat.view.menu.MenuBuilder;
import androidx.appcompat.view.menu.MenuItemImpl;
import androidx.appcompat.widget.TintTypedArray;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import com.google.android.material.bottomnavigation.BottomNavigationMenu;
import com.google.android.material.internal.ThemeEnforcement;
import com.scorpio.baselibrary.ScreenAdapterTools;
import com.scorpio.baselibrary.utils.DisplayUtils;
import com.sm.scorpio.R;

import java.util.ArrayList;
import java.util.List;

/**
 * created by zhud on 2019/5/31
 */
@SuppressLint({"RestrictedApi", "ResourceType"})
public class SMBottomNavigationView extends LinearLayout implements View.OnClickListener {
    private static final int BOTTOM_HEIGHT_PX = 160;
    private Context mContext;
    private MenuInflater mMenuInflater;
    private MenuBuilder mMenuBuilder;
    private List<BottomNavigationItem> mMenuItemView = new ArrayList<>();
    private Paint mPaint;
    private int mLineColor = Color.parseColor("#AAAAAA");
    private int mIndex = -1;
    private int mNormalColor = Color.parseColor("#666666");
    private int ico_single_color = Color.parseColor("#666666");
    private int mSelectedColor;
    private int mBottomHeight = 0;


    private int ico_width = 72;
    private int ico_height = 72;
    private int ico_extrude_width = 120;
    private int ico_extrude_height = 120;
    private int ico_single_width = 120;
    private int ico_single_height = 120;
    private int meun_text_size = 48;

    private int mExtrudeMenuIndex = -1;
    private FragmentManager mFm;
    private Fragment pre_fragment;
    private List<Fragment> mFragments;
    private OnNavigationItemSelectedListener mOnNavigationItemSelectedListener;
    private int mLayoutFrameId = -1;
    private int menuItemCont;

    public SMBottomNavigationView(Context context) {
        this(context, null);
    }

    public SMBottomNavigationView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.bottomNavigationStyle);
    }

    public SMBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        mMenuBuilder = new BottomNavigationMenu(context);
        TintTypedArray typedArray = ThemeEnforcement.obtainTintedStyledAttributes(context, attrs, R.styleable.BottomNavigationView, defStyleAttr, R.style.Widget_Design_BottomNavigationView, new int[]{R.styleable.BottomNavigationView_itemTextAppearanceInactive, R.styleable.BottomNavigationView_itemTextAppearanceActive});
        if (typedArray.hasValue(R.styleable.BottomNavigationView_menu)) {
            this.inflateMenu(typedArray.getResourceId(R.styleable.BottomNavigationView_menu, 0));
        }
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SMBottomNavigationView);
        mExtrudeMenuIndex = array.getInteger(R.styleable.SMBottomNavigationView_extrudeMenuIndex, mExtrudeMenuIndex);
        mLayoutFrameId = array.getResourceId(R.styleable.SMBottomNavigationView_fram_layout_id, mLayoutFrameId);
        mSelectedColor = getColorPrimary();
        ico_width = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_height, ico_width);
        ico_height = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_height, ico_height);
        ico_extrude_width = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_extrude_width, ico_extrude_width);
        ico_extrude_height = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_extrude_height, ico_extrude_height);
        ico_single_width = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_single_width, ico_single_width);
        ico_single_height = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_ico_single_height, ico_single_height);
        meun_text_size = array.getDimensionPixelSize(R.styleable.SMBottomNavigationView_text_size, meun_text_size);
        mLineColor = array.getColor(R.styleable.SMBottomNavigationView_top_line_color, mLineColor);
        ico_single_color = array.getColor(R.styleable.SMBottomNavigationView_ico_single_color, ico_single_color);
        mNormalColor = array.getColor(R.styleable.SMBottomNavigationView_normalColor, mNormalColor);
        mSelectedColor = array.getColor(R.styleable.SMBottomNavigationView_selectedColor, mSelectedColor);

        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        initPaint();
        init();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setColor(mLineColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(DisplayUtils.dip2px(getContext(), 1));
        mPaint.setAntiAlias(true);
    }

    private void init() {
        mBottomHeight = BOTTOM_HEIGHT_PX;
        ArrayList<MenuItemImpl> menuItems = mMenuBuilder.getNonActionItems();
        menuItemCont = menuItems.size();
        for (int i = 0; i < menuItems.size(); i++) {
            MenuItemImpl item = menuItems.get(i);
            BottomNavigationItem itemLayout = factureItemView();
            itemLayout.textView.setText(item.getTitle());
            mMenuItemView.add(itemLayout);
            if (TextUtils.isEmpty(item.getTitle())) {
                itemLayout.showBigImage();
                itemLayout.imageBigView.setImageDrawable(tintDrawable(item.getIcon(), ico_single_color));
            } else {
                itemLayout.imageView.setImageDrawable(item.getIcon());
            }
            itemLayout.itemLayout.setOnClickListener(this);
            addView(itemLayout.itemLayout);
        }
        setClipChildren(false);
        setExtrudeMenu(mExtrudeMenuIndex);
        updateOnClick();
    }

    public void setSelectedItem(int index) {
        if (mIndex == index) return;
        MenuItemImpl item = mMenuBuilder.getNonActionItems().get(index);
        if (item != null) {
            if (mOnNavigationItemSelectedListener != null) {
                mOnNavigationItemSelectedListener.onNavigationItemStartSelected(mIndex, index);
            }
            if (!TextUtils.isEmpty(item.getTitle())) {
                mIndex = index;
                onNavigationItemSelected(index, item.getItemId());
                updateOnClick();
            }
            if (mOnNavigationItemSelectedListener != null) {
                mOnNavigationItemSelectedListener.onNavigationItemEndSelected(mIndex);
            }
        }
    }

    /**
     * 设置连接fragment
     *
     * @param fragments
     * @param fm
     */
    public void setLinkageFragments(List<? extends Fragment> fragments, FragmentManager fm) {
        this.mFragments = (List<Fragment>) fragments;
        this.mFm = fm;
        if (mIndex >= 0) {
            MenuItemImpl item = mMenuBuilder.getNonActionItems().get(mIndex);
            if (item != null && !TextUtils.isEmpty(item.getTitle())) {
                onNavigationItemSelected(mIndex, item.getItemId());
            }
        }
    }

    @Override
    public void onClick(View v) {
        for (int i = 0; i < mMenuItemView.size(); i++) {
            BottomNavigationItem navigationItem = mMenuItemView.get(i);
            if (navigationItem.itemLayout.equals(v)) {
                setSelectedItem(i);
                break;
            }
        }
    }

    private void onNavigationItemSelected(int index, int item_id) {
        if (mFragments == null || mFragments.size() == 0) return;
        Fragment fragment = mFm.findFragmentByTag(index + "-" + item_id);
        if (fragment == null && mLayoutFrameId != -1) {
            fragment = mFragments.get(index);
            if (fragment == null) return;
            mFm.beginTransaction().add(mLayoutFrameId, fragment, index + "-" + item_id).commit();
        }
        if (pre_fragment != null) mFm.beginTransaction().hide(pre_fragment).commit();
        if (fragment != null) mFm.beginTransaction().show(fragment).commit();
        pre_fragment = fragment;
    }

    private void updateOnClick() {
        for (int i = 0; i < mMenuItemView.size(); i++) {
            BottomNavigationItem navigationItem = mMenuItemView.get(i);
            TextView textView = navigationItem.textView;
            if (navigationItem.isShowBigImage()) {
                ImageView imageBigView = navigationItem.imageBigView;
                imageBigView.setImageDrawable(tintDrawable(imageBigView.getDrawable(), ico_single_color));
            } else {
                ImageView imageView = navigationItem.imageView;
                imageView.setImageDrawable(tintDrawable(imageView.getDrawable(), i == mIndex ? mSelectedColor : mNormalColor));
                imageView.setImageState(i == mIndex ? new int[]{android.R.attr.state_selected} : StateSet.NOTHING, true);
            }
            textView.setTextColor(i == mIndex ? mSelectedColor : mNormalColor);
        }
    }

    private BottomNavigationItem factureItemView() {
        ViewGroup view = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.layout_buttom_navigation_item, null);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1f);
        view.setLayoutParams(params);
        view.setOnClickListener(this);

        ImageView imageView = view.findViewById(R.id.sm_buttom_navigation_icon);
        ConstraintLayout.LayoutParams imageViewParams = (ConstraintLayout.LayoutParams) imageView.getLayoutParams();
        imageViewParams.width = ico_width;
        imageViewParams.height = ico_height;
        imageView.setLayoutParams(imageViewParams);

        ImageView imageBigView = view.findViewById(R.id.sm_buttom_navigation_big_icon);
        imageViewParams = (ConstraintLayout.LayoutParams) imageBigView.getLayoutParams();
        imageViewParams.width = ico_single_width;
        imageViewParams.height = ico_single_height;
        imageBigView.setLayoutParams(imageViewParams);

        TextView textView = view.findViewById(R.id.sm_buttom_navigation_text);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, meun_text_size);
        return new BottomNavigationItem(view, imageView, imageBigView, textView);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(0, 0, getWidth(), 0, mPaint);
    }


    public void inflateMenu(int resId) {
        this.getMenuInflater().inflate(resId, mMenuBuilder);
    }

    //设置突出的菜单按钮
    public void setExtrudeMenu(int index) {
        if (index == -1) return;
        mExtrudeMenuIndex = index;
        for (int i = 0; i < mMenuItemView.size(); i++) {
            ImageView imageView = mMenuItemView.get(i).imageView;
            if (imageView == null) continue;
            ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) imageView.getLayoutParams();
            params.width = i == index ? ico_extrude_width : ico_width;
            params.height = i == index ? ico_extrude_height : ico_height;
            imageView.setLayoutParams(params);
        }
    }

    private MenuInflater getMenuInflater() {
        if (mMenuInflater == null) {
            mMenuInflater = new SupportMenuInflater(this.getContext());
        }
        return mMenuInflater;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int minimumWidth = getSuggestedMinimumWidth();
        final int minimumHeight = getSuggestedMinimumHeight();
        int width = measureWidth(minimumWidth, widthMeasureSpec);
        int height = measureHeight(minimumHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);

    }

    private int measureWidth(int defaultWidth, int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        switch (specMode) {
            case MeasureSpec.AT_MOST:
                defaultWidth = Math.max(defaultWidth, specSize);
                break;
            case MeasureSpec.EXACTLY:
                defaultWidth = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                defaultWidth = Math.max(defaultWidth, specSize);
        }
        return defaultWidth;
    }

    private int measureHeight(int defaultHeight, int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        switch (specMode) {
            case MeasureSpec.AT_MOST:
                defaultHeight = mBottomHeight;
                break;
            case MeasureSpec.EXACTLY:
                defaultHeight = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                defaultHeight = Math.max(defaultHeight, specSize);
                break;
        }
        return defaultHeight;
    }

    public int getColorPrimary() {
        TypedValue typedValue = new TypedValue();
        mContext.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
        return typedValue.data;
    }

    /**
     * 重绘Drawable，将drawable颜色着色为color
     *
     * @param drawable
     * @param color
     * @return 重绘后的Drawable
     */
    private Drawable tintDrawable(Drawable drawable, int color) {
        DrawableCompat.setTint(drawable, color);
        return drawable;
    }

    public void setOnNavigationItemSelectedListener(OnNavigationItemSelectedListener mnNavigationItemSelectedListener) {
        this.mOnNavigationItemSelectedListener = mnNavigationItemSelectedListener;
    }

    public interface OnNavigationItemSelectedListener {
        void onNavigationItemStartSelected(int current_id, int target_id);

        void onNavigationItemEndSelected(int target_id);
    }

    class BottomNavigationItem {
        ViewGroup itemLayout;
        ImageView imageView;
        ImageView imageBigView;
        TextView textView;

        public BottomNavigationItem(ViewGroup itemLayout, ImageView imageView, ImageView imageBigView, TextView textView) {
            this.itemLayout = itemLayout;
            this.imageView = imageView;
            this.imageBigView = imageBigView;
            this.textView = textView;
        }

        public void showBigImage() {
            textView.setVisibility(GONE);
            imageView.setVisibility(GONE);
            imageBigView.setVisibility(VISIBLE);
        }

        private boolean isShowBigImage() {
            return imageBigView.getVisibility() == VISIBLE;
        }
    }
}
